package com.jxin.mall.config.plan;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jxin.mall.config.consts.RedisTempTypeEnum;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;

/**
 * redis的序列化方案
 * @author 蔡佳新
 * @version 1.0
 * @since jdk 1.8
 */
public class RedisSerializerPlan {
    /**
     * 获取json参数的自定义json序列化器
     * @param  type 模板类型
     * @return {@link Jackson2JsonRedisSerializer} json 序列化器
     * @author 蔡佳新
     */
    public static RedisSerializer<Object> valueSerializer(Integer type){
        // protoStuff序列化
        if(RedisTempTypeEnum.PROTOBUF_TEMP.getType().equals(type)
           || RedisTempTypeEnum.MULTI_PROTOBUF_TEMP.getType().equals(type)){
            return new ProtobufRedisSerializer<>(Object.class);
        }
        // 默然采用json序列化
        final Jackson2JsonRedisSerializer<Object> objectJackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        objectJackson2JsonRedisSerializer.setObjectMapper(getObjectMapper(type));
        return objectJackson2JsonRedisSerializer;
    }
    /**
     * 获得对象映射器
     * @param  type 模板类型
     * @return {@link ObjectMapper} 对象映射器
     * @author 蔡佳新
     */
    private static ObjectMapper getObjectMapper(Integer type) {
        final ObjectMapper result = new ObjectMapper();
        // 用于反序列化的时候知道用什么类去序列化
        result.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        result.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        // 不知道的类型就不序列化了
        result.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);

        // 缓存的redis模板 null也缓存，以便于降低空查询对数据库的压力
        if(RedisTempTypeEnum.CACHE_TEMP.getType().equals(type)){
            result.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        }
        return result;
    }
}
